﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BetterPlaceAdmin
{
    public partial class frmMain : Form
    {

        private BetterServiceReference.Customer _customer;
        private BetterServiceReference.Route _route;
        private IList<BetterServiceReference.Subscription> _subscriptions;
        private int counter = 300;
        

        //Lav en reference til Serviceklienten
        static BetterServiceReference.IBookingService bookObj = new BetterServiceReference.BookingServiceClient();
        
        //Indlæs frmMain klassen der initialiserer ListBoxe, TextBoxe mv.
        public frmMain()
        {
            InitializeComponent();
        }

        //Når formen startes angives hvad der skkal loades. Herunder bliver diverse ListBoxe initialiseret 
        //ListBox.DataSource er det data der skal læses ind i formen
        //ListBox.DisplayMember er den property på DataTier der skal vises. 
        //Der bruges DisplayMember fordi public override string ToString() ikke virker gennem WCF
        private void frmMain_Load(object sender, EventArgs e)
        {
            existingCustomerListBox.DataSource = bookObj.GetAllCustomers();
            existingCustomerListBox.DisplayMember=  "Name";
            existingCustomerListBox2.DataSource = bookObj.GetAllCustomers();
            existingCustomerListBox2.DisplayMember = "Name";
            stationListBox.DataSource = bookObj.GetAllStations();
            stationListBox.DisplayMember = "StationName";
            stationBatteryListBox.DataSource = bookObj.GetAllStations();
            stationBatteryListBox.DisplayMember = "StationName";
            stationsComboBox.DataSource = bookObj.GetAllStations();
            stationsComboBox.DisplayMember = "StationName";
            fromStationComboBox.DataSource = bookObj.GetAllStations();
            fromStationComboBox.DisplayMember = "StationName";
            toStationComboBox.DataSource = bookObj.GetAllStations();
            toStationComboBox.DisplayMember = "StationName";
            routeFromComboBox.DataSource = bookObj.GetAllStations();
            routeFromComboBox.DisplayMember = "StationName";
            routeToComboBox.DataSource = bookObj.GetAllStations();
            routeToComboBox.DisplayMember = "StationName";
            routeCustomerComboBox.DataSource = bookObj.GetAllCustomers();
            routeCustomerComboBox.DisplayMember = "Name";

        }


        //Indlæs alle værdier i existingCustomerListBox igen
        private void UpdateCustomers()
        {
            existingCustomerListBox.BeginUpdate();
            existingCustomerListBox.DataSource = bookObj.GetAllCustomers();
            existingCustomerListBox.DisplayMember = "Name";
            existingCustomerListBox.EndUpdate();
        }

        //Indlæs alle værdier i stationListBox og stationsComboBox igen
        private void UpdateStations()
        {
            stationListBox.BeginUpdate();
            stationListBox.DataSource = bookObj.GetAllStations();
            stationListBox.DisplayMember = "StationName";
            stationListBox.EndUpdate();
            stationsComboBox.BeginUpdate();
            stationsComboBox.DataSource = bookObj.GetAllStations();
            stationsComboBox.DisplayMember = "StationName";
            stationsComboBox.EndUpdate();
        }

        //Ryd kundefelter på Opret Kunde fanebladet
        private void ClearCustomers()
        {
            nameTextBox.Clear();
            addressTextBox.Clear();
            zipTextBox.Clear();
            cityTextBox.Clear();
            userNameTextBox.Clear();
            passwordTextBox.Clear();
            emailTextBox.Clear();
        }

       //Det der skal ske når man flytter focus på existingCustomerListBox
        //Her udfyldes alle TextBoxene med kundedetaljer, når man skifter kundenavn i ListBoxen
        private void existingCustomerListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            BetterServiceReference.Customer selected = (BetterServiceReference.Customer)existingCustomerListBox.SelectedItem;
            exCustIdTextBox.Text = selected.CustomerId.ToString();
            exCustNameTextBox.Text = selected.Name;
            exCustAddressTextBox.Text = selected.Address;
            exCustZipTextBox.Text = selected.ZipCode.ToString();
            exCustCityTextBox.Text = selected.City;
            exCustEmailTextBox.Text = selected.Email;
            exCustPasswordTextBox.Text = selected.Password;
            exCustUserNameTextBox.Text = selected.UserName;
        }

        //Slet knappen på Kunde fanebladet. Der læses et kundenummer ud af TextBoxen, som bruges til at slette kunden gennem WCF
        //Der er implementeret en pop up besked der spørger om man er sikker på at man vil slette
        //Efter sletning, opdateres kundeListBoxen, så man kan se kunden er væk.
        private void btnDelete_Click(object sender, EventArgs e)
        {
            BetterServiceReference.Customer selected = (BetterServiceReference.Customer)existingCustomerListBox.SelectedItem;
            int id = (Convert.ToInt32(exCustIdTextBox.Text));
            if (
            MessageBox.Show("Er du sikker på at du vil slette " +
                            selected.Name + "? - Kunden kan ikke genskabes", "Slet "
                            + selected.Name,
                            MessageBoxButtons.YesNo, MessageBoxIcon.Information)
            == DialogResult.Yes
       )
            bookObj.DeleteCustomerById(id);
            UpdateCustomers();
        }

        //Manuel opdatering af Kundelistbox
        private void button1_Click(object sender, EventArgs e)
        {
            UpdateCustomers();
        }

        //Knap til opdatering af kunde. Alle TextBoxes værdier omsættes til variabler, således at det er muligt at opdatere alle værdier på kunden
        //Igen er der implementeret en popup, der sikrer at man ikke gør noget utilsigtet
        //KundeID kan ikke opdateres (det er lavet i DBCustomer, men bruges til at vælge den kunde der skal opdateres - dette sikrer at man kan opdatere alle felter)
        //Igen opdateres kunder efter metoden er afviklet for at se at kunden er ændret. 
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            BetterServiceReference.Customer selected = (BetterServiceReference.Customer)existingCustomerListBox.SelectedItem;
            int id = (Convert.ToInt32(exCustIdTextBox.Text));
            string uName = exCustUserNameTextBox.Text;
            string name = exCustNameTextBox.Text;
            string address = exCustAddressTextBox.Text;
            int zip = (Convert.ToInt32(exCustZipTextBox.Text));
            string email = exCustEmailTextBox.Text;
            string password = exCustPasswordTextBox.Text;
            if (
            MessageBox.Show("Er du sikker på at du vil opdatere " +
                            selected.Name + "?", "Opdater "
                            + selected.Name,
                            MessageBoxButtons.YesNo, MessageBoxIcon.Information)
            == DialogResult.Yes
       )
            bookObj.UpdateCustomer(id, uName, name, address, zip, email, password);
            UpdateCustomers();
        }

        //Knap til at rydde alle felter på opret kunde
        private void button3_Click(object sender, EventArgs e)
        {
            ClearCustomers();
        }

        //Oprettelse af kunde.
        //Felter udlæses til variabler, der bruges til at oprette kunde gennem WCF
        //Implementeret popup
        //Efter metodeafvikling opdatares kundeListBoxen på "Eksisterende kunder" fanebladet, alle felter ryddes
        //Der skiftes fokus til "Eksisterende kunder" fanebladet, og den sidst oprettede kunde markeres, så man hurtigt kan få et overblik
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                string uname = userNameTextBox.Text;
                string name = nameTextBox.Text;
                string address = addressTextBox.Text;
                int zip = (Convert.ToInt32(zipTextBox.Text));
                string email = emailTextBox.Text;
                string password = passwordTextBox.Text;
            if (
          MessageBox.Show("Er du sikker på at du vil oprette " +
                          name + "?", "Opret "
                          + name,
                          MessageBoxButtons.YesNo, MessageBoxIcon.Information)
          == DialogResult.Yes
     )
               

                    bookObj.CreateCustomer(uname, name, address, zip, email, password);
                    UpdateCustomers();
                    ClearCustomers();
                    tabControl2.SelectedTab = tabPage4;
                    existingCustomerListBox.SelectedIndex = existingCustomerListBox.Items.Count - 1;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Kunne ikke oprette kunde " + ex.Message);
                }
        }

        //Når der indtastes et postnr bliver textboxen til by automatisk opdaret til den rette by
        private void zipTextBox_TextChanged(object sender, EventArgs e)
        {
            try
            {
                if (zipTextBox.TextLength == 4)
                    cityTextBox.Text = bookObj.GetCityFromZip(Convert.ToInt32(zipTextBox.Text));
            }

            catch (Exception ex)
            {
                MessageBox.Show("Hallo " + ex.Message);
            }
        }

        //Herunder bliver edgeListBox automatisk opdateret med de rette Edges, som den station der vælges i stationListBox har
        //Derudover bliver TextBoxe med detaljer om stationen opdateret med de rette værdier. 
        private void stationListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            BetterServiceReference.Station selected = (BetterServiceReference.Station)stationListBox.SelectedItem;
     
            foreach (BetterServiceReference.Edge ed in selected.Edges)
            {
                if (ed.From.StationId == selected.StationId)
                {
                    
                    edgeListBox.DataSource=selected.Edges;
                    edgeListBox.DisplayMember = "ToStation";
                }
            }
            stationNameTextBox.Text = selected.StationName;
            stationAddressTextBox.Text = selected.StationAddress;
            stationCityTextBox.Text = selected.City;
            stationZipTextBox.Text = selected.ZipCode.ToString();
           
        }

        //Km til forbindelse textboxen opdateres med Cost værdien for den enkelte Edge man har markeret i edgeListBox
        private void edgeListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            BetterServiceReference.Edge edgeSelect = (BetterServiceReference.Edge)edgeListBox.SelectedItem;
            edgeCostTextBox.Text = edgeSelect.Cost.ToString();
        }

        //Hver gang man markerer en ny station på stationBatteryListBox (batteri faneblad under Stationer) skal der vises de battterier der er tilknyttet den markerede station
        //Listen af Batterier genereres vha et dbkald via WCF. Der laves et nyt kald hver gang der skiftes markering på stationBatteryListBoxen
        private void stationBatteryListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            BetterServiceReference.Station selected = (BetterServiceReference.Station)stationBatteryListBox.SelectedItem;
            List<BetterServiceReference.Battery> batList = new List<BetterServiceReference.Battery>(bookObj.GetBatteriesInStation(selected.StationId));
            batteryListBox.DataSource = batList;
            batteryListBox.DisplayMember = "BatteryId";
        }

        //Batteriernes variabler tilskrives de enkelte textboxe, når der skiftes markering på batteryListBoxen
        private void batteryListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            BetterServiceReference.Battery batSelect = (BetterServiceReference.Battery)batteryListBox.SelectedItem;
            percentChargedTextBox.Text = batSelect.PercentCharged.ToString();
            timesChargedTextBox.Text = batSelect.TimesCharged.ToString();
            batteryModelTextBox.Text = batSelect.BatteryModel.BatteryModelId.ToString();
        }

        //Når man klikker på "Tilføj batteri til station" knappen skal der oprettes et nyt batteri
        //og indsættes på den station der er markeret i stationBatteryListBoxen.
        //Implementeret en popup.
        //Slutteligt opdateres batteryListBoxen, for at man kan se det nye batteri. 
        private void button1_Click_1(object sender, EventArgs e)
        {
            BetterServiceReference.Station selected = (BetterServiceReference.Station)stationBatteryListBox.SelectedItem;
            if(
                MessageBox.Show("Er du sikker på du vil tilføje et nyt batteri til " +
                selected.StationName +"?", "Tilføj batteri til "
                    +selected.StationName,
            MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes
                )
            bookObj.AddBatteryToStation(selected.StationId);
            batteryListBox.BeginUpdate();
            List<BetterServiceReference.Battery> batList = new List<BetterServiceReference.Battery>(bookObj.GetBatteriesInStation(selected.StationId));
            batteryListBox.DataSource = batList;
            batteryListBox.DisplayMember = "BatteryId";
            batteryListBox.EndUpdate();
        }

        //Knap til at oprette en ny station. Der indsættes værdier fra txtboxe i variabler, der kan sendes
        //til database gennem WCF. Implementeret en popup.
        //Derefter ryddes alle txtboxe, og man sendes til Stationer fanebladet, med besked om at man skal huske at oprette en forbindelse.
        //på stationListBox flyttes fokus til nyest oprettede station, for at give et bedre overblik
        private void Opret_Click(object sender, EventArgs e)
        {
               try
            {
                string name = createStationNameTextBox.Text;
                string address = createStationAddressTextBox.Text;
                int zip = (Convert.ToInt32(createStationZipTextBox.Text));

            
            if (
          MessageBox.Show("Er du sikker på at du vil oprette " +
                          name + "?", "Opret "
                          + name,
                          MessageBoxButtons.YesNo, MessageBoxIcon.Information)
          == DialogResult.Yes
     )
               

                    bookObj.CreateStation(name, address, zip);
                    UpdateStations();
                    createStationNameTextBox.Clear();
                   createStationZipTextBox.Clear();
                   createStationAddressTextBox.Clear();
                   createStationCityTextBox.Clear();
                    tabControl3.SelectedTab = tabPage6;
                    stationListBox.SelectedIndex = stationListBox.Items.Count - 1;
                   MessageBox.Show("Husk at oprette mindst 1 forbindelse til den nye station");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Kunne ikke oprette station " + ex.Message);
                }
        }

        //Når der indtastes et postnr skal byen automatisk sættes på cityTxtboxen
        private void stationZipTextBox_TextChanged(object sender, EventArgs e)
        {
            int zip = (Convert.ToInt32(stationZipTextBox.Text));
            try
            {
                if (stationZipTextBox.TextLength == 4)
                    stationCityTextBox.Text = bookObj.GetCityFromZip(zip);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Hallo " + ex.Message);
            }
        }

        //Knap til at oprette forbindelse mellem 2 stationer. Da forbindelserne er uorienterede
        //skal der oprettes en forbindelse med samme km mellem "from og to" og "to og from"
        //From er den station der er valgt i stationListBox
        //To er den station der er valgt i comboboxen
        //Implementeret Popup
        private void button5_Click(object sender, EventArgs e)
        {
            BetterServiceReference.Station fromSelected = (BetterServiceReference.Station)stationListBox.SelectedItem;
            BetterServiceReference.Station toSelected = (BetterServiceReference.Station)stationsComboBox.SelectedItem;
            int cost = Convert.ToInt32(edgeCostTextBox.Text);
            if (
          MessageBox.Show("Er du sikker på at du vil oprette en forbindelse mellem " +
                          fromSelected.StationName + " og "+toSelected.StationName +"?", "Opret forbindelse fra "
                          + fromSelected.StationName,
                          MessageBoxButtons.YesNo, MessageBoxIcon.Information)
          == DialogResult.Yes
     )
            bookObj.CreateEdge(fromSelected.StationId, toSelected.StationId, cost);
            bookObj.CreateEdge(toSelected.StationId, fromSelected.StationId, cost);
            UpdateStations();

        }

        //Knap til at opdatere stationer
        private void updateStationsButton_Click(object sender, EventArgs e)
        {
            UpdateStations();
        }

        //Knap til at slette en station
        //Der udføres et databasekald gennem WCF, der først sletter edges fra stationen, derefter edges til stationen
        //Slutteligt slettes stationen
        private void deleteStationButton_Click(object sender, EventArgs e)
        {
            BetterServiceReference.Station selected = (BetterServiceReference.Station)stationListBox.SelectedItem;
            if (
          MessageBox.Show("Er du sikker på at du vil slette stationen " +
                          selected.StationName + "?", "Slet station "
                          + selected.StationName,
                          MessageBoxButtons.YesNo, MessageBoxIcon.Information)
          == DialogResult.Yes
     )
            bookObj.DeleteEdgeTo(selected.StationId);
            bookObj.DeleteEdgeFrom(selected.StationId);
            bookObj.DeleteStation(selected.StationId);
        }

        //Validering af gyldig email adresse
        //RegEx (regular expression/regulær udtryk) bruges til at validere en email adresse.
        //Valideringen sker når man flytter fokus fra emailTxtBoxen, forudsat der er skrevet noget i den
        //Kan textboxen ikke valideres kommer der en popup, der fortæller at det ikke er en gyldig email adresse
        //Klikker man OK ryger man tilbage til email txtboxen, som er markeret, så man kan skrive i den.
        private void emailTextBox_Validating(object sender, CancelEventArgs e)
        {
            System.Text.RegularExpressions.Regex rEMail = new System.Text.RegularExpressions.Regex(@"^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$");
            if (emailTextBox.Text.Length > 0)
            {
                if (!rEMail.IsMatch(emailTextBox.Text))
                {
                    MessageBox.Show("Du skal indtaste en gyldig E-mail adresse", "Gyldig E-mail mangler", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    emailTextBox.SelectAll();
                    e.Cancel = true;
                }
            }
        }

        //Når man trykker på "Find Rute" knappen bliver fromStationComboBoxen og toStationComboBoxens indhold
        //smidt ind i et db kald gennem WCF
        //ListBoxe og labels sættes til synlige, og udfyldes med værdier fra metoderne. 
        private void findRouteButton_Click(object sender, EventArgs e)
        {
            BetterServiceReference.Station fromStation = (BetterServiceReference.Station)fromStationComboBox.SelectedItem;
            BetterServiceReference.Station toStation = (BetterServiceReference.Station)toStationComboBox.SelectedItem;
            BetterServiceReference.Station s = bookObj.FindShortestRoute(fromStation.ZipCode, toStation.ZipCode);
            routeListBox.Visible = true;
            pathSumListBox.Visible = true;
            routePathSumLabel.Visible = true;
            routeStationNameLabel.Visible = true;
            routeDescLabel1.Visible = true;
            routeDescLabel2.Visible = true;
            routeDescLabel2.Text = s.PathSum.ToString();
            routeDescLabel3.Visible = true;
            routeDescLabel4.Visible = true;
            routeDescLabel4.Text = toStation.StationName;
            routeDescLabel5.Visible = true;
            routeDescLabel6.Visible = true;
            routeDescLabel6.Text = s.Connection.Count().ToString();
            routeDescLabel7.Visible = true;
            foreach (BetterServiceReference.Station station in s.Connection)
            {
                routeListBox.DataSource = s.Connection;
                routeListBox.DisplayMember = "StationName";
                pathSumListBox.DataSource = s.Connection;
                pathSumListBox.DisplayMember = "PathSum";
            }
        }

        //createStationCityTextBox skal opdateres gennem dbkald gennem wcf når der er indtastet postnr
        private void createStationZipTextBox_TextChanged(object sender, EventArgs e)
        {
            try
            {
                if (createStationZipTextBox.TextLength == 4)
                    createStationCityTextBox.Text = bookObj.GetCityFromZip(Convert.ToInt32(createStationZipTextBox.Text));
            }
            catch (Exception ex)
            {
                MessageBox.Show("Hallo " + ex.Message);
            }
        }

        private void existingCustomerlistBox2_SelectedIndexChanged(object sender, EventArgs e)
        {


            

            BetterServiceReference.Customer selected = (BetterServiceReference.Customer)existingCustomerListBox2.SelectedItem;

            List<BetterServiceReference.Subscription> subList = new List<BetterServiceReference.Subscription>(bookObj.GetSubscriptions(selected.CustomerId));
            subscriptionListBox.DataSource = subList;
            subscriptionListBox.DisplayMember = "SubscriptionId";
            
            //List<BetterServiceReference.Booking> bod = new List<BetterServiceReference.Booking>();
          
            //bindingSource1.CopyTo(a, 1);
            //  foreach (BetterServiceReference.Booking b in bookObj.getAllBookings())
            //  {
            //          bod.Add(b);
            //  }

            //          getAllBookingslistBox1.DataSource = bod;

            //          getAllBookingslistBox1.DisplayMember = "bookingId";

               

            }
              
        


        private void exCustIdTextBox_TextChanged(object sender, EventArgs e)
        {

        }


        private void button4_Click(object sender, EventArgs e)
        {

        }

        private void bindingSource1_CurrentChanged(object sender, EventArgs e)
        {
           
        }

        private void pictureBox7_Click(object sender, EventArgs e)
        {

        }

        private void subscriptionListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            //BetterServiceReference.Subscription subSelected = (BetterServiceReference.Subscription)subscriptionListBox.SelectedItem;
            //List<BetterServiceReference.Booking> bookList = new List<BetterServiceReference.Booking>(bookObj.getAllBookings(subSelected.SubscriptionId));
            //bookingsListBox.DataSource = bookList;
            //bookingsListBox.DisplayMember = "BookingId";
        }

        private void bookRouteBtn_Click(object sender, EventArgs e)
        {
            BetterServiceReference.Station from = (BetterServiceReference.Station)routeFromComboBox.SelectedItem;
            BetterServiceReference.Station to = (BetterServiceReference.Station)routeToComboBox.SelectedItem;
            _customer = (BetterServiceReference.Customer)routeCustomerComboBox.SelectedItem;
            _subscriptions = bookObj.GetSubscriptions(_customer.CustomerId);
            DateTime dTime = DateTime.Now;
            //dTime.AddYears(dateTimePicker1.Value.Year);
            //dTime.AddMonths(dateTimePicker1.Value.Month);
            //dTime.AddDays(dateTimePicker1.Value.Day);
            //dTime.AddHours(dateTimePicker1.Value.Hour);
            //dTime.AddMinutes(dateTimePicker1.Value.Minute);
            DateTime theDate = dateTimePicker1.Value;
            IList<BetterServiceReference.Station> stations = bookObj.GetAllStations();
            _route = bookObj.CalculateRoute(from.ZipCode, from.City, from.StationAddress, true, theDate, to.ZipCode, to.City, to.StationAddress, _customer, _subscriptions[0]);
            //bookRouteRichTextBox.Text += String.Join(Environment.NewLine, Environment.NewLine, _route.RouteId, _route.FromCity, _route.ToCity);
            bookRouteRichTextBox.Text += ("Fra "+ _route.FromCity+"\t Til: "+ _route.ToCity+"\n");
            foreach (BetterServiceReference.Booking booking in _route.Bookings)
            {
                bookRouteRichTextBox.Text += ("Dato: "+ booking.BookingDate+"\n");

                foreach (BetterServiceReference.Station station in stations)
                {
                    foreach (BetterServiceReference.Battery battery in station.Batteries)
                    {
                        if (battery.BatteryId == booking.Battery.BatteryId)
                        {
                            bookRouteRichTextBox.Text += ("Batteriskifte bookes i: \t"+ station.StationName+"\n");
                        }
                    }
                }



            }
            int counter = 300;
            timer1 = new System.Windows.Forms.Timer();
            timer1.Tick += new EventHandler(timer1_Tick);
            timer1.Interval = 1000; // 1 second
            timer1.Start();
            lblCountDown.Text = "Du har reserveret batteriet i "+counter.ToString()+" sekunder";
        }


        private void acceptBookingBtn_Click(object sender, EventArgs e)
        {
            bookObj.AcceptRoute(_route, _customer, _subscriptions[0]);
            MessageBox.Show("Booking er oprettet");
            bookRouteRichTextBox.Clear();

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            counter--;
            if (counter == 0)
                timer1.Stop();
            lblCountDown.Text = "Du har reserveret batteriet i "+counter.ToString()+" sekunder";
        }

    }
}